/*
 * AIEngine a new generation network intrusion detection system.
 *
 * Copyright (C) 2013-2023  Luis Campo Giralte
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA  02110-1301, USA.
 *
 * Written by Luis Campo Giralte <luis.camp0.2009@gmail.com> 
 *
 */
#ifndef _TEST_TCP_H_
#define _TEST_TCP_H_

#include <string>
#include <vector>
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include "Protocol.h"
#include "StackTest.h"
#include "../vlan/VLanProtocol.h"
#include "../ip/IPProtocol.h"
#include "../ip6/IPv6Protocol.h"
#include "TCPProtocol.h"

using namespace aiengine;

struct StackTCPTest : public StackTest
{
        IPProtocolPtr ip;
        TCPProtocolPtr tcp;
        MultiplexerPtr mux_ip;
        MultiplexerPtr mux_tcp;

       // FlowManager and FlowCache
        FlowManagerPtr flow_mng;
        FlowCachePtr flow_cache;

       	StackTCPTest()
        {
                tcp = TCPProtocolPtr(new TCPProtocol());
                ip = IPProtocolPtr(new IPProtocol());
                mux_ip = MultiplexerPtr(new Multiplexer());
                mux_tcp = MultiplexerPtr(new Multiplexer());

                // configure the ip
                ip->setMultiplexer(mux_ip);
                mux_ip->setProtocol(static_cast<ProtocolPtr>(ip));

                // configure the tcp 
                tcp->setMultiplexer(mux_tcp);
                mux_tcp->setProtocol(static_cast<ProtocolPtr>(tcp));

                // configure the multiplexers
                mux_eth->addUpMultiplexer(mux_ip);
                mux_ip->addDownMultiplexer(mux_eth);
                mux_ip->addUpMultiplexer(mux_tcp);
                mux_tcp->addDownMultiplexer(mux_ip);

                // Allocate the flow caches and tables
                flow_mng = FlowManagerPtr(new FlowManager());
                flow_cache = FlowCachePtr(new FlowCache());

		flow_mng->setFlowCache(flow_cache);

                // Connect the FlowManager and FlowCache
                flow_cache->create(2);
                tcp->createTCPInfos(2);

                tcp->setFlowCache(flow_cache);
                tcp->setFlowManager(flow_mng);

		ip->setAnomalyManager(anomaly);
		tcp->setAnomalyManager(anomaly);
        }

	void statistics() {
		tcp->statistics(std::cout, 5, 0);
	}

        ~StackTCPTest() {}
};

struct StackIPv6TCPTest : public StackTest
{
        IPv6ProtocolPtr ip6;
        TCPProtocolPtr tcp;
        MultiplexerPtr mux_ip;
        MultiplexerPtr mux_tcp;

        StackIPv6TCPTest()
        {
                tcp = TCPProtocolPtr(new TCPProtocol());
                ip6 = IPv6ProtocolPtr(new IPv6Protocol());
                mux_ip = MultiplexerPtr(new Multiplexer());
                mux_tcp = MultiplexerPtr(new Multiplexer());

                //configure the eth
                eth->setMultiplexer(mux_eth);
                mux_eth->setProtocol(static_cast<ProtocolPtr>(eth));

                // configure the ip
                ip6->setMultiplexer(mux_ip);
                mux_ip->setProtocol(static_cast<ProtocolPtr>(ip6));

                // configure the tcp
                tcp->setMultiplexer(mux_tcp);
                mux_tcp->setProtocol(static_cast<ProtocolPtr>(tcp));

                // configure the multiplexers
                mux_eth->addUpMultiplexer(mux_ip);
                mux_ip->addDownMultiplexer(mux_eth);
                mux_ip->addUpMultiplexer(mux_tcp);
                mux_tcp->addDownMultiplexer(mux_ip);
		
		ip6->setAnomalyManager(anomaly);
		tcp->setAnomalyManager(anomaly);
        }

        ~StackIPv6TCPTest() {}
};

#endif
